<template>
    <div class="display" ref="display">
        <div class="dialogue" ref="dialogue">
            <ComBanner @getQuestion="getQuestion"></ComBanner>
            <ul class="list">
                <li :class="['item',item.sender]" v-for="(item,index) in chatList" :key="index">
                    <img v-if="item.sender !== 'system'" class="img" :src="item.senderAvatar" alt="" >
                    <template v-if="item.sender === 'system'" >
                        <div v-if="true">{{item.content}} </div>
                        <div v-else><span>{{item.content}}</span>为你服务 </div>
                    </template>
                    <template v-else-if="item.sender === 'client'">
                        <div class="service">
                            <div class="content">
                                <img v-if="item.type === 'img'" class="imgSrc" :src="item.imgSrc" alt="">
                                <span  v-else class="text">{{ item.content }}</span>
                            </div>
                        </div>
                    </template>
                    <template  v-else-if="item.sender === 'gpt'">
                        <div class="gpt_service">
                            <div class="staff">智能AI客服</div>
                            <span v-if="index === chatList.length -1 && item.thinking" class="text">正在思考中...</span>
                            <div v-else class="content">
                                <div  :class="['contentText',index === chatList.length -1 && isLoading &&'loading']">{{ item.content }}</div>
                                <div class="prompt" v-if="index === chatList.length -1? answering :true">
                                    <div class="p_left">
                                        <span class="iconfont icon icon-31tishi"></span>
                                        <span class="promptText">此回复由AI生成，仅供参考</span>
                                    </div>
                                    <div class="p_right">
                                        <span :class="['iconfont','icon','icon-dianzan1']" @click="item.status === 0 && praise($event,index,item.messageId )"></span>
                                        <span :class="['iconfont','icon','tread','icon-dianzan1']" @click=" item.status === 0 && tread($event,index,item.messageId)"></span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </template>
                    <template v-else-if="item.sender === 'agent'">
                        <div class="service">
                            <div class="staff">{{ item.senderName }}</div>
                            <div class="content">
                                <img v-if="item.type === 'img'" class="imgSrc" :src="item.imgSrc" alt="">
                                <div  v-else class="text">{{ item.content }}</div>
                            </div>
                        </div>
                    </template>
                </li>
            </ul>
        </div>
        <div ref="tabBar" class="tabBar">
            <div v-if="false" class="stop" >
                <img src="@/assets/image/stop.png" alt="" class="stop_img">
                <span class="stop_test">停止生成</span>
            </div>
            <div class="footer">
                <ul class="contact">
                    <li class="item">
                        <a href="tel:400-8600-993">
                            <span class="iconfont icon icon-a-dianhua1"></span>
                            <span class="text">客服电话</span>
                        </a>
                    </li>
                    <li :class="['item',answerer === 1 && 'isOver']" @click.stop="changeOver">
                        <span class="iconfont icon icon-kefu-ermai"></span>
                        <span class="text">人工客服</span>
                    </li>
                    <li class="item" @click="openFeedback">
                        <span class="iconfont icon icon-a-pingjia21"></span>
                        <span class="text">评价与反馈</span>
                    </li>
                </ul>
                <div class="message">
                    <div class="camera">
                        <input id="file" type="file" ref="file"  @change="checkFile"/>
                        <label for="file"><span class="iconfont icon icon-tupianshangchuan"></span></label>
                    </div>
                    <form action="#" @submit="openSend">
                        <textarea class="inp" ref="details" :rows="rows" v-model.trim="chatMsg" placeholder="请在此输入你的问题"></textarea>
                        <div class="send" @click="openSend"></div>
                    </form>
                </div>
            </div>
        </div>
    </div>
    <!--    showFeedback-->
    <ComFeedback :sessionId="sessionId || null" :showFeedback="showFeedback" @closeFeedback="closeFeedback" />
    <!--    showDialog-->
    <ComDialog :treadData="treadData" :ShowDialog="showDialog" @closeDialog="closeDialog" @winCloseDialog="winCloseDialog"/>
</template>

<script setup>
import {getCurrentInstance, nextTick, onBeforeUnmount, onMounted, ref, watch,watchEffect } from 'vue';
import compressImg from '@/utils/compressImg.js'
import { debounce } from 'lodash-es';
import {useWebSocket} from '@vueuse/core'
import {stringify,parse} from 'qs'
import ComBanner from "@/components/comBanner.vue";
import ComDialog from "@/components/ComDialog.vue";
import ComFeedback from "@/components/ComFeedback.vue";
import {getFeedbackMessage} from "@/utils/api.js";
import {ElMessage} from "element-plus";

const { proxy } = getCurrentInstance();
const { mittBus } = proxy;

const dialogue = ref()
const details = ref()
const chatList = ref([])// 聊天数据
const chatMsg = ref() // 对话文本
const thought = ref(false)// 思考中
const answering = ref(false)// 回答中
const interFlow = ref(false)// 快捷问题
const showDialog = ref(false) // Gpt内容反馈
const showFeedback = ref(false) // 评价与反馈
const treadData = ref({}) // Gpt内容反馈
const heartbeat = ref(false)

const isLoading = ref(false)
const sessionId = ref(null)// 对话id

const isTypeImg = ref('txt') // 对话id
const answerer = ref(0)//gpt 0 坐席1
let webSocketUrl = ref(import.meta.env.VITE_WS_ADDRESS_URL)
const CTK = localStorage.getItem('CTK')
let socket1
let socket2
mittBus.on('CTK',(v)=>{
    socket1 = webSocket({CTK:v, answerer:answerer.value})
    // socket1 = webSocket(v,answerer.value)
})
function exists(CTK){
    if(CTK)  socket1 = webSocket({CTK, answerer:answerer.value})
}


// 发送
function openSend(event){
    event.preventDefault()
    if(chatMsg.value === '') return
    thought.value = true
    sendMsg(false,chatMsg.value)
}


// 发送快捷回复
function getQuestion(v){
    thought.value = true
    sendMsg(true,v)
}
// 发送消息方法
function sendMsg(isQuickReply,content){
    const obj = {
        content,
        sender:'client',
        type:isTypeImg.value,
        finished:true,
        senderAvatar:'src/assets/image/user.png'
    }
    chatList.value.push(obj)
    nextTick(()=>{
        dialogue.value.scrollTop = dialogue.value.scrollHeight
    })
    let  data = {
        input: content,
        businessCode:'generate',
        customerServicePlatform:'myl',
        sessionId:sessionId.value,
        type:isTypeImg.value,
    }
    if(answerer.value===1){
        delete data.customerServicePlatform
    }
    operation(answerer.value===0?socket1:socket2,'Send',JSON.stringify(data))
    if(!isQuickReply){
        chatMsg.value = ''
    }
    // WatchData()
}
// 发送图片
const file = ref()
function checkFile(){
    const newFile = file.value.files[0]
    compressImg(newFile,0.1).then(res => {//compressImg方法见附录
        console.log(res)
    })
}
// 人工客服
const changeOver =debounce(() =>{
    operation(socket1,'Close')
    CloseSocket()
    heartbeat.value = true
},16)
function  CloseSocket(){
    let time
    time = setInterval(()=>{
        const  status = operation(socket1,'Status')
        if(status  === 'CLOSED'){
            if(answerer.value === 1) return
            answerer.value = 1
            socket2 = webSocket({CTK, answerer:answerer.value})
            clearInterval(time)
        }
    },10)
}

// 赞
function praise(e,i,messageId){
    getFeedbackMessage({feedback: 1,messageId}).then(v =>{
        if(v.c === '100'){
            e.target.classList.remove('icon-dianzan1')
            e.target.classList.add('icon-dianzan')
            chatList.value[i].status = 1
        }
    })
}
// 踩
function tread(e,i,messageId){
    console.log(124)
    showDialog.value = true
    treadData.value = {
        messageId,
        myIndex: i,
        event: e
    }
}
// 踩踏评论
function winCloseDialog(value){
    showDialog.value = false
    let {event,myIndex} = value
    event.target.classList.remove('icon-dianzan1')
    event.target.classList.add('icon-dianzan')
    chatList.value[myIndex].status = -1
}
function closeDialog(value) {
    showDialog.value = value
}


// 评价反馈
function openFeedback() {
    if(sessionId.value === '' ||sessionId.value === null) return  ElMessage({
        message: '暂时无法评价',
        type: 'warning',
        grouping: true
    })
    showFeedback.value =true
}
function closeFeedback(value) {
    showFeedback.value =value
}

// 输入框高度自适应
const rows = ref(1)
let tabBar = ref()
const display = ref()
function adjustTextareaSize(){
    const textarea = details.value
    textarea.addEventListener('input', (e) => {
        textarea.style.height = 'auto';
        if(e.target.scrollHeight > 100){
            textarea.style.height =  '100px';
        }else {
            textarea.style.height = e.target.scrollHeight + 'px';
        }
    });
    dialogue.value.style.height = (display.value.scrollHeight-tabBar.value.scrollHeight)+'px'
    dialogue.value.scrollTop = dialogue.value.scrollHeight
}


watch(() => chatMsg.value, (v) => {
    nextTick(()=>{adjustTextareaSize()});
},{immediate:true})



// 判断手机机型
function isIos(){
    const u = navigator.userAgent;
    const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //Android
    const isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //iOS
    if(isAndroid){
        file.value.capture = 'camera'
        file.value.accept = 'image/*'
    }
}
onMounted(()=>{
    exists(CTK)
    nextTick(()=>{adjustTextareaSize()});
    isIos()
})

// websocket
function webSocket(params){
    const { status,send, open, close } = useWebSocket(`${webSocketUrl.value}?${stringify(params)}`,{
        onMessage(ws,e){
            watchSocket(JSON.parse(e.data))
        }
    })
    return {status, send, open, close}
}

// websocket 操作
function operation(Socket,StatusNum,data = undefined){
    if(StatusNum === 'Send' && data){
        Socket.send(data)
        return
    }
    if(StatusNum === 'Status'){
        return Socket.status.value
    }
    if(StatusNum === 'Close'){
        return Socket.close()
    }
    // if(StatusNum === 'Data'){
    //     return JSON.parse(Socket.data.value)
    // }
    // if(StatusNum === 'newData'){
    //     console.log(Socket.newData)
    //     return Socket.newData
    // }
}
// 流逝返回
let text = ref('')
let a = 0,b =0
function WatchData(){
    if(answerer.value === 0){
        watch(()=>operation(socket1,'Data'),(v)=>{
            thought.value = false
            watchSocket(v)
        })
    }
    if(answerer.value === 1){
        watch(()=>operation(socket2,'newData'),(v,o)=>{
            // if(v && v !== o){
            //     watchSocket(v)
            // }
            console.log(v)
        })
        // watchEffect(()=>{
        //    let data = operation(socket2,'Data')
        //     console.log('data',data)
        //      watchSocket(data)
        // })

    }
}

// 返回数据处理
function watchSocket(data){
    let item
    let content
    let thinking
    switch(data?.c){
        case '100':
            sessionId.value = data.d.sessionId
            content = data.d.content
            thinking = data.d.thinking
            item = addItem(data.d)
            break;
        case '200':
            addItem(data)
            item = ''
            break;
        case '401':
            item = ' '
            break;
        case '600':
            item = addItem(data.d)
            break;
        case '601':
            item = addItem(data.d)
            break;
        default:
            item = addItem(data.d)
    }
    if(answerer.value === 0){
        isLoading.value = true
        text.value += content
        if(chatList.value[chatList.value.length-1].finished){
            chatList.value.push(item)
        }
        if(data?.c === '200'){
            chatList.value[chatList.value.length-1].thinking = false
        }
        // console.log('finished1',data?.d.finished)
        if(!data?.d.finished){
            chatList.value[chatList.value.length-1].content =  text.value
            chatList.value[chatList.value.length-1].thinking =  thinking
            chatList.value[chatList.value.length-1].status =  0
        }else {
            text.value = ''
            isLoading.value = false
        }
        nextTick(()=>{
            dialogue.value.scrollTop = dialogue.value.scrollHeight
        })
        answering.value = data?.d.finished || false
    }else {
        // console.log(item)
        // if(chatList.value[chatList.value.length-1])
        chatList.value.push(item)
        nextTick(()=>{
            dialogue.value.scrollTop = dialogue.value.scrollHeight
        })
    }
}

// 数据处理
function addItem(...data){
    let obj = {}
    let arr = data[0]
    for (let key in arr) {
        if(key === 'finished' && arr?.finished === false){
            obj.content += arr?.content
        }else {
            obj[key] = arr[key]
        }
    }
    return obj
}

onBeforeUnmount(()=>{
    mittBus.off('CTK')
    operation(answerer.value === 0?socket1:socket2,'Close')
})
// 刷新事件
document.addEventListener("visibilitychange", function() {
    if (document.visibilityState === 'hidden') {
        if(answerer.value === 0){
            operation(socket1,'Close')
        }else {
            if(socket2){
                operation(socket2,'Close')
            }
        }
    }
});
</script>

<style lang="scss" scoped>
.display{
    width: 100%;
    height: 100vh;
    background: #F1F9FF;
    flex-direction: column;
    padding: 0 30px;
    box-sizing: border-box;
    overflow: hidden;
    .dialogue{
        width: 100%;
        height: calc(100% - 300px);
        overflow-y: auto;
        -ms-overflow-style: none;
        .list{
            display: flex;
            flex-direction: column;
            gap: 30px 0;
            margin-bottom: 10px;
            .item{
                width: 100%;
                display: flex;
                align-items: flex-start;
                .img{
                    width: 58px;
                    height: 58px;
                    border-radius: 50%;
                }
                .service{
                    width: 534px;
                    margin-left: 20px;
                    .staff{
                        display: inline-block;
                        font-size: 24px;
                        color: #3D3D3D;
                        line-height: 42px;
                    }
                    .content{
                        margin-top: 10px;
                        border-radius: 0 15px 15px 15px;
                        word-break: break-all;
                        box-sizing: border-box;
                        padding: 20px;
                        background: #fff;
                        font-size: 28px;
                        color: #3D3D3D;
                        white-space: pre-wrap;
                        line-height: 50px;
                        flex-direction: column;
                        .imgSrc{
                            width: 260px;
                        }
                    }
                }

                &.client{
                    flex: 1;
                    flex-direction: row-reverse;
                    .img{
                        margin-top: 15px;
                    }
                    .service{
                        margin-right: 20px;
                        display: flex;
                        justify-content: flex-end;
                        .content{
                            margin-top: 0;
                            background: #D8EFFF;
                            border-radius: 15px 0 15px 15px;
                            padding: 24px 20px;
                        }
                    }
                }
                &.gpt{
                    flex: 1;
                    .gpt_service{
                        margin-left: 20px;
                        width: 534px;
                        .staff{
                            font-size: 24px;
                            color: #3D3D3D;
                            line-height: 42px;
                        }
                        .text{
                            display: inline-block;
                            background: #FFFFFF;
                            padding: 24px 20px;
                            font-size: 28px;
                        }
                        .content{
                            margin-top: 10px;
                            border-radius: 0 15px 15px 15px;
                            color: #0B0E0E;
                            line-height: 40px;
                            white-space:pre-wrap;
                            padding: 24px 20px;
                            background: #FFFFFF;
                            .contentText {
                                font-size: 28px;
                                color: #3D3D3D;
                                line-height: 50px;
                                word-break: break-all;
                                white-space: pre-wrap;
                                @keyframes BLINK {
                                    to {
                                        visibility: hidden
                                    }
                                }
                                &.loading::after {
                                    -webkit-animation: BLINK 1s steps(5, start) infinite;
                                    animation: BLINK 1s steps(5, start) infinite;
                                    content: "▎";
                                    font-size: 16px;
                                    left: 23px;
                                    transform: translateY(-50%) scaleX(.7);
                                    vertical-align: baseline
                                }
                            }
                            .prompt{
                                position: relative;
                                margin-top: 16px;
                                display: flex;
                                &:before{
                                    position: absolute;
                                    content: '';
                                    display: inline-block;
                                    height: 1px !important;
                                    width: 100%;
                                    background: #F4F4F4;
                                }
                                .p_left{
                                    margin-top: 16px;
                                    flex: 1;
                                    color: #BABABA;
                                    display: flex;
                                    align-items: center;
                                    .icon{
                                        font-size: 28px;
                                    }
                                    .promptText{
                                        margin-left: 6px;
                                        font-size: 24px;
                                    }
                                }
                                .p_right{
                                    margin-top: 16px;
                                    margin-left: auto;
                                    margin-right: 0;
                                    display: flex;
                                    gap: 0 30px;
                                    .icon{
                                        font-size: 28px;
                                        color: #3D3D3D;
                                    }
                                    .icon-dianzan{
                                        color: #197CFD;
                                    }
                                    .tread{
                                        transform: rotateZ(-180deg);
                                    }
                                }
                            }
                            .answering{
                                display: flex;
                                .img{
                                    width: 30px;
                                    height: 30px;
                                }
                            }
                        }
                    }
                }
                &.system{
                    font-family: "Regular", serif;
                    font-size: 24px;
                    font-weight: 400;
                    width: 500px;
                    line-height: 42px;
                    color: #8C8C8C;
                    margin: 0 auto;
                    text-align: center;
                    justify-content: center;
                    span{
                        color: #197CFD
                    }
                }
                &.agent{
                    flex: 1;
                    .service{
                        margin-right: 20px;
                        display: flex;
                        justify-content: flex-end;
                        flex-direction: column;
                        .content{
                            .text{
                                display: inline-block;
                            }
                        }
                    }
                }
            }
        }
        &::-webkit-scrollbar { width: 0 !important }
    }
    .tabBar{
        width: 100%;
        position: fixed;
        bottom: 0;
        left: 50%;
        transform: translateX(-50%);
        //padding:30px 0 0;
        .stop{
            width: 190px;
            height: 60px;
            background: #e0edf7b3;
            box-shadow: 0 18px 26px 0 rgba(154,193,230,0.39);
            border-radius: 30px;
            color:#187CFD ;
            margin: 0 auto 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            .stop_img{
                width: 30px;
                height: 30px;
            }
            .stop_test{
                margin-left: 10px;
                font-size: 24px;
            }
        }
        .footer{
            width: 100%;
            padding:0 20px 30px;
            box-sizing: border-box;
            background: #fff;
            display: flex;
            flex-direction: column;
            .contact{
                display: flex;
                align-items: center;
                gap: 0 20px;
                margin: 20px 0;
                height: 48px;
                .item{
                    padding: 0 20px;
                    height: 48px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    border-radius: 30px;
                    background: #F1F9FF;
                    cursor: pointer;
                    a{
                        text-decoration:none;
                        height: 48px;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                    }
                    .icon{
                        color: #197CFD;
                        font-size: 24px;
                    }
                    .text{
                        font-family: "Regular",serif;
                        font-size: 24px;
                        margin-left: 6px;
                        color: #3D3D3D;
                    }
                    &.isOver{
                        background: #F1F9FF;
                        .text{
                            color: #8C8C8C;
                        }
                    }
                }
            }
            .message{
                width: 690px;
                border: 2px solid #197CFD;
                border-radius: 50px;
                margin: 0 auto ;
                display: flex;
                align-items:center;
                justify-content: space-between;
                padding: 10px 0;
                .camera{
                    margin: 0 20px;
                    .icon{
                        color: #D4E4F9;
                        font-size: 32px;
                    }
                    input{
                        display: none;
                        //overflow: hidden;
                    }
                    label{
                        display: flex;
                        justify-items: center;
                        align-items: center;
                    }
                }
                form{
                    flex: 1;
                    display: flex;
                    align-items: center;
                }
                .inp{
                    padding: 10px 0 ;
                    margin: auto 0 auto 10px;
                    box-sizing: border-box;
                    flex: 1;
                    line-height: 40px;
                    -ms-overflow-style: none;
                    border: none;
                    resize: none;
                    outline: none;
                    font-size: 28px;
                    &::-webkit-input-placeholder{
                        color: #BABABA;
                        font-size: 24px;
                    }
                    &::-webkit-scrollbar {
                        width: 0 !important;
                        line-height: 100%;
                    }
                }
                .send{
                    width: 70px;
                    height: 70px;
                    border-radius: 50%;
                    margin-right: 10px;
                    margin-left: 20px;
                    background: #197CFD url('@/assets/image/happen.png') center / 30px no-repeat;
                }
            }
        }
    }
}
</style>